<?php

namespace app\common\library;

use GuzzleHttp\Client;
use WeChatPay\Builder;
use WeChatPay\Crypto\Rsa;
use WeChatPay\Util\PemUtil;
use EasyWeChat\Factory;
/**
 * 支付类
 */
class Payment
{

    /**
     * 微信app支付不依赖三方库
     * @param $trade_type JSAPI--JSAPI支付（或小程序支付）、NATIVE--Native支付、APP--app支付，MWEB--H5支付
     * @return
     */
    public static function wechatAppPay($title ,$trade_no, $trade_type = 'APP', $amount = 0, $openid = '')
    {
        $pay_url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
        $config  = config('wechat');
        $param['appid']  = $config['appid'];          //服务商商户的APPID
        $param['mch_id'] = $config['mchid'];                  //微信支付分配的商户号
        $param['nonce_str'] = randomString(32);
        $param['body'] = $title;
        $param['out_trade_no'] = $trade_no;
        $param['fee_type']  = 'CNY';
        $param['total_fee'] = $amount*100;   //单位是分乘以100
        $param['spbill_create_ip'] =  request()->ip();
        $param['notify_url'] = $config['notify_url'];
        $param['trade_type'] = $trade_type;
        $param['openid'] = $openid;
        $param['sign_type'] = 'MD5';
        $param['sign'] = self::wechat_sign($param, $config['key']);
        $str = self::ArrToXml($param);
        $result = self::curl_post($pay_url, $str);
        //print_r($result);exit;
        $result = self::xmlToArray($result);


        //print_r($result);exit;
        if($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS')
        {
            if($trade_type == 'JSAPI')
            {
                $return_data['appId']     = $result['appid'];
                $return_data['timeStamp'] = time();
                $return_data['nonceStr']  = $param['nonce_str'];
                $return_data['package']   = 'prepay_id='.$result['prepay_id'];
                $return_data['signType']  = 'MD5';
                $return_data['paySign']   =  self::wechat_sign($return_data, $config['key']); //这里需要第二次签名才可以


                return $return_data;

            }elseif ($trade_type == 'APP')
            {
                $return_data['appid']     = $result['appid'];
                $return_data['partnerid'] = $result['mch_id'];
                $return_data['prepayid']  = $result['prepay_id'];
                $return_data['package']   = 'Sign=WXPay';
                $return_data['noncestr']  = $param['nonce_str'];
                $return_data['timestamp'] = time();
                $return_data['sign']      = self::wechat_sign($return_data, $config['key']);

                return $return_data;

            }elseif ($trade_type == 'NATIVE'){
                


            }elseif($trade_type == 'MWEB'){

                $return_data['trade_type'] = $trade_type;
                $return_data['prepay_id']  = $result['prepay_id'];
                $return_data['mweb_url']   = $result['mweb_url'];

                return $return_data;
            }else{
                  return [];  
            }

        }else{
            return [];
        }
    }

    public static function generate_sign($attributes, $key, $encryptMethod = 'md5')
    {
        ksort($attributes);

        $attributes['key'] = $key;

        return strtoupper(call_user_func_array($encryptMethod, [urldecode(http_build_query($attributes))]));
    }

    //生成微信签名
    public static function wechat_sign($data, $mach_key)
    {
        //签名步骤一：按字典序排序参数
        ksort($data);
        $string = self::ToUrlParams($data);
        //签名步骤二：在string后加入KEY
        $string = $string . "&key=".$mach_key;
        //签名步骤三：MD5加密或者HMAC-SHA256
        $string = md5($string);
        //签名步骤四：所有字符转为大写
        $result = strtoupper($string);
        return $result;
    }

    public static function ToUrlParams($param)
    {
        $buff = "";
        foreach ($param as $k => $v)
        {
            if($k != "sign" && $v != "" && !is_array($v)){
                $buff .= $k . "=" . $v . "&";
            }
        }

        $buff = trim($buff, "&");
        return $buff;
    }

    public static function ArrToXml($arr)
    {
        $xml = "<xml>";
        foreach ($arr as $key=>$val)
        {
            $xml.="<".$key.">".$val."</".$key.">";
        }
        $xml.="</xml>";
        return $xml;
    }

    public static function xmlToArray($xml)
    {
        //禁止引用外部xml实体
        libxml_disable_entity_loader(true);
        $values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        return $values;
    }

    public static function curl_post($url , $data=array()){

        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, $url);

        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);

        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        // POST数据
        curl_setopt($ch, CURLOPT_POST, 1);
        // 把post的变量加上
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

        $output = curl_exec($ch);
        curl_close($ch);
        return $output;
    }





}
